#include "DuLink.h"
#include <iostream>

// 构造函数
DuLink::DuLink() {
    head = nullptr; // 初始化头指针为空
    tail = nullptr; // 初始化尾指针为空
    len = 0;        // 初始化长度为0
}

// 析构函数
DuLink::~DuLink() {
    node* current = head; // 从头节点开始
    node* nextNode; // 用于保存下一个节点

    // 遍历链表，逐个删除节点
    while (current != nullptr) {
        nextNode = current->next; // 先保存下一个节点
        delete current; // 删除当前节点
        current = nextNode; // 移动到下一个节点
    }

    head = nullptr; // 清空头指针
    tail = nullptr; // 清空尾指针
    len = 0;        // 重置长度
}


// 获取链表长度
int DuLink::length() const {
    return len; // 返回长度
}

// 获取指定位置的数据
int DuLink::getData(const int& location) const {
    if (location < 0 || location >= len) return -1; // 超出范围

    node* current = head; // 从头节点开始
    for (int i = 0; i < location; ++i) {
        current = current->next; // 遍历到指定位置
    }
    return current->value; // 返回值
}

// 插入元素
void DuLink::insert(const int& data, const int& location) {
    if (location < 0 || location > len) return; // 超出范围

    node* newNode = new node; // 创建新节点
    newNode->value = data; // 设置值
    newNode->next = nullptr; // 初始化新节点的next指针
    newNode->prev = nullptr; // 初始化新节点的prev指针

    if (len == 0) { // 插入到空链表
        head = newNode; // 新节点成为头节点
        tail = newNode; // 新节点也成为尾节点
    } else if (location == 0) { // 插入到链表头部
        newNode->next = head; // 新节点的next指向当前头节点
        head->prev = newNode; // 当前头节点的prev指向新节点
        head = newNode; // 更新头节点
    } else if (location == len) { // 插入到链表尾部
        newNode->prev = tail; // 新节点的prev指向当前尾节点
        tail->next = newNode; // 当前尾节点的next指向新节点
        tail = newNode; // 更新尾节点
    } else {
        node* current = head; // 从头节点开始
        for (int i = 0; i < location; ++i) {
            current = current->next; // 遍历到插入位置的节点
        }
        newNode->next = current; // 新节点的next指向当前位置的节点
        newNode->prev = current->prev; // 新节点的prev指向当前位置的前一个节点
        current->prev->next = newNode; // 前一个节点的next指向新节点
        current->prev = newNode; // 当前节点的prev指向新节点
    }

    len++; // 增加链表长度
}

// 删除指定位置的元素
bool DuLink::remove(const int& location) {
    if (location < 0 || location >= len) return false; // 超出范围

    node* toDelete = head;

    if (location == 0) { // 删除头节点
        head = head->next; // 更新头节点
        if (head) {
            head->prev = nullptr; // 更新新头节点的prev指针
        } else {
            tail = nullptr; // 如果链表变空，尾指针也设为空
        }
    } else if (location == len - 1) { // 删除尾节点
        toDelete = tail; // 将要删除的节点设为尾节点
        tail = tail->prev; // 更新尾节点
        if (tail) {
            tail->next = nullptr; // 更新新尾节点的next指针
        } else {
            head = nullptr; // 如果链表变空，头指针也设为空
        }
    } else {
        for (int i = 0; i < location; ++i) {
            toDelete = toDelete->next; // 找到要删除的节点
        }
        toDelete->prev->next = toDelete->next; // 跳过要删除的节点
        if (toDelete->next) {
            toDelete->next->prev = toDelete->prev; // 跳过要删除的节点
        }
    }

    delete toDelete; // 删除节点
    len--; // 减少链表长度
    return true; // 删除成功
}


// 翻转链表
void DuLink::converse() {
    if (len <= 1) return; // 如果链表为空或只有一个节点，直接返回

    node* current = head;
    node* temp = nullptr;

    // 遍历链表，交换每个节点的前后指针
    while (current) {
        temp = current->prev; // 保存前一个节点
        current->prev = current->next; // 交换前后指针
        current->next = temp; // 交换前后指针

        current = current->prev; // 移动到下一个节点（注意此时为旧的next）
    }

    // 交换头尾指针
    if (temp) {
        tail = head; // 更新尾节点
        head = temp->prev; // 更新头节点
    }
}

// 拼接另一个双向链表
    void DuLink :: append(const DuLink& append_list){
    if (append_list.len == 0) return; // 如果要拼接的链表为空，直接返回

    if (len == 0) { // 当前链表为空
        head = append_list.head; // 将头指针指向要拼接的链表的头
        tail = append_list.tail; // 将尾指针指向要拼接的链表的尾
    } else {
        tail->next = append_list.head; // 将当前尾节点指向要拼接链表的头节点
        append_list.head->prev = tail; // 要拼接链表的头节点的prev指向当前尾节点
        tail = append_list.tail; // 更新当前链表的尾节点
    }

    len += append_list.len; // 更新当前链表的长度
}